package com.zzf.concurrent.example.wait;

import com.zzf.concurrent.example.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.stream.IntStream;

/**
 * @author GaoFeng2017
 * @date 2019/8/12 19:40
 */
@Slf4j
public class WaitSetExample {

    private final static Object LOCK = new Object();

    /**
     * 一个线程调用wait方法后，会被进入blocked状态，释放同步锁1的所有权并存放在waitset中
     * waitset的存放和读取不是有序的
     *
     * */
    public static void main(String[] args) {
        IntStream.rangeClosed(1, 10).forEach(i -> {
            new Thread(() -> {
                synchronized (LOCK) {
                    log.info("{} will be blocked, {} push to wait set.", Thread.currentThread().getName(), i);
                    TimeUtil.sleep((long) (Math.random() * 1000));
                    try {
                        LOCK.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    // 重新获取同步锁，从上一次的代码单元地址开始执行
                    log.info("{} will be get monitor, {} pop of wait set.", Thread.currentThread().getName(), i);
                }

            }, String.valueOf(i)).start();
        });

        TimeUtil.sleep(8000L);

        log.info("notify all waiter.");
        synchronized (LOCK) {
            LOCK.notifyAll();
        }
    }

    public static void main() {

    }
}
